﻿using AuSys.Database.Context;
using AuSys.Repos;
using AuSys.Services.App;
using AuSys.Services.App.FileStorage;
using AuSys.Services.App.Logging;
using AuSys.Services.App.UserInfo.Abstractions;
using AuSys.Test.Repos.App.TestSupport;
using AuSys.Test.TestSupport.Fakes;
using Microsoft.Data.Sqlite;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace AuSys.Test.TestSupport
{
    public class TestServiceProvider
    {
        private readonly IServiceProvider _serviceProvider;
        public const string tempPath = "Temp";
        public TestServiceProvider() 
        {
            ServiceCollection services = new();
            IConfiguration config = new ConfigurationBuilder().AddInMemoryCollection(
                new Dictionary<string, string?>
                {
                    ["Jwt:Domain"] = "jowei19.com",
                    ["Jwt:SecretKey"] = "123456789",
                    ["FileStorage:Type"] = "NoNeed",
                    ["TempPath"] = tempPath
                }).Build();
            services.AddSingleton(config);
            services.AddSerilog(config);
            services.AddAppServices(config);
            services.AddRepoServices();

            services.AddSingleton<FakeFileStorage>();
            services.AddSingleton<IFileStorage>((sp) => sp.GetRequiredService<FakeFileStorage>());

            services.AddScoped<FakeUserIdProvider>();
            services.AddScoped<IUserIdProvider>((sp) => sp.GetRequiredService<FakeUserIdProvider>());

            var connection = new SqliteConnection("Data Source=:memory:");connection.Open();
            services.AddSingleton(connection);
            services.AddScoped<FakeDataContext>();
            services.AddScoped<DataContext>((sp) => sp.GetRequiredService<FakeDataContext>());
            services.AddScoped<MockRepo>();
            services.AddScoped<MockRepoCache>();
            services.AddScoped<MockRepoTree>();

            _serviceProvider = services.BuildServiceProvider();
        }
        public T Get<T>()
        {
            var res = _serviceProvider.GetService<T>() 
                ?? throw new NotImplementedException();
            return res;
        }
        public IServiceScope CreateScope()
            => _serviceProvider.CreateScope();
    }
}
